package com.sita.bike.utils;

import android.app.Activity;
import android.bluetooth.BluetoothAdapter;
import android.content.Intent;
import android.widget.Toast;

import com.sita.bike.R;
import com.sita.bike.support.GlobalContext;
import com.sita.tboard.util.BluetoothDataAnalysis;

import java.util.ArrayList;
import java.util.List;

import app.akexorcist.bluetotohspp.library.BluetoothSPP;
import app.akexorcist.bluetotohspp.library.BluetoothState;
import app.akexorcist.bluetotohspp.library.DeviceList;

/**
 * Created by hongyun on 2016/3/29.
 */
public class BluetoothUtils {

    private final static String TAG = BluetoothUtils.class.getSimpleName();

    private static BluetoothSPP bt = GlobalContext.getBluetoothSPP();
    private static List<BluetoothDataListener> mBlueToothDataListenerList = new ArrayList<>();
    private static List<BluetoothServiceListener> mBlueToothServiceListenerList = new ArrayList<>();
    private static boolean mIsAutoConnected = false;
    private static boolean mHasShowedFailedMessage = false;
    private static boolean mIsConnecting = false;
    private static boolean mIsConnected = false;

    /**
     * no popup "enable bluetooth" prompt
     */
    public static void setNoBluetoothPrompt() {
        LocalStorage.setEnableBluetoothPrompt(false);
    }

    public static boolean getBluetoothPromptEnabled() {
        return LocalStorage.getBluetoothPromptEnabled();
    }

    public interface BluetoothServiceListener {
        public void onDeviceConnected();

        public void onDeviceDisconnected();

        public void onDeviceConnectionFailed();
    }

    public static void initBluetooth(final Activity activity, final BluetoothServiceListener listener) {
        if (!bt.isBluetoothAvailable()) {
            Toast.makeText(activity
                    , GlobalContext.getGlobalContext().getString(R.string.bluetooth_connect_off)
                    , Toast.LENGTH_SHORT).show();
        }
        addServiceListener(listener);
        bt.setBluetoothConnectionListener(new BluetoothSPP.BluetoothConnectionListener() {
            public void onDeviceConnected(String name, String address) {
                Toast.makeText(activity
                        , GlobalContext.getGlobalContext().getString(R.string.bluetooth_connect_ok) + name
                        , Toast.LENGTH_SHORT).show();
                //蓝牙连接成功后保存本次的连接设备信息
                LocalStorage.setBluetoothAddress(address);
                mIsConnecting = false;
                mIsConnected = true;
                sendConnected();

            }

            public void onDeviceDisconnected() {
                Toast.makeText(activity
                        , GlobalContext.getGlobalContext().getString(R.string.bluetooth_connect_loss)
                        , Toast.LENGTH_SHORT).show();
                mIsConnecting = false;
                mIsConnected = false;
                sendConnectLoss();

            }

            public void onDeviceConnectionFailed() {
                if (isNeedShowFailedMessage()) {
                    Toast.makeText(activity
                            , GlobalContext.getGlobalContext().getString(R.string.bluetooth_connect_failed)
                            , Toast.LENGTH_SHORT).show();
                    setFailedMessageShowed();
                }
                mIsConnecting = false;
                mIsConnected = false;
                sendConnectFailed();

            }
        });
    }

    private static boolean isNeedShowFailedMessage() {
        if (mIsAutoConnected && mHasShowedFailedMessage) {
            return false;
        }
        return true;

    }

    private static void setFailedMessageShowed() {
        mHasShowedFailedMessage = true;
    }

    public static void connect(Intent data) {
        mIsAutoConnected = false;
        mIsConnecting = true;
        bt.connect(data);
    }

    public static void disconnect() {
        bt.disconnect();
        mIsConnecting = false;
        mIsConnected = false;
    }

    public static void scanBluetoothDevice(Activity activity) {
        // here set the autoShowPrompt = true
        LocalStorage.setEnableBluetoothPrompt(true);

        if (bt.isBluetoothEnabled()) {
            Intent intent = new Intent(activity, DeviceList.class);
            activity.startActivityForResult(intent, BluetoothState.REQUEST_CONNECT_DEVICE);
        } else {
            Intent intent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
            activity.startActivityForResult(intent, BluetoothState.REQUEST_ENABLE_BT);
        }
    }

    public static void startService() {
        bt.setupService();
        bt.startService(BluetoothState.DEVICE_OTHER);
    }

    public static boolean autoConnect() {
        if (mIsConnecting || mIsConnected) {
            return true;
        }
        boolean result = false;
        String address = LocalStorage.getBluetoothAddress();
        if (address != "") {
            mIsAutoConnected = true;
            bt.connect(address);
            result = true;
        }
        return result;
    }

    public static boolean startBlueToothService(Activity activity) {
        boolean result = true;
        if (!bt.isBluetoothEnabled()) {
            if (BluetoothUtils.getBluetoothPromptEnabled()) {
                Intent intent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
                activity.startActivityForResult(intent, BluetoothState.REQUEST_ENABLE_BT);
            }
            result = false;
        } else {
            if (!bt.isServiceAvailable()) {
                startService();
            }
        }
        return result;
    }

    public static boolean isBluetoothConnected() {
        return bt.getServiceState() == BluetoothState.STATE_CONNECTED;
    }

    public interface BluetoothDataListener {
        public void onDataReceived(int speed, int rpm, int shift);
    }

    private static long startBtTime = System.currentTimeMillis();

    private static void addServiceListener(BluetoothServiceListener listener) {
        if (!mBlueToothServiceListenerList.contains(listener)) {
            mBlueToothServiceListenerList.add(listener);
        }
    }

    public static void unregisterServiceListener(BluetoothServiceListener listener) {
        if (listener != null && mBlueToothServiceListenerList.contains(listener)) {
            mBlueToothServiceListenerList.remove(listener);
        }
    }

    private static void sendConnected() {
        for (BluetoothServiceListener listener : mBlueToothServiceListenerList
                ) {
            if (listener != null) {
                listener.onDeviceConnected();
            }
        }
    }

    private static void sendConnectLoss() {
        for (BluetoothServiceListener listener : mBlueToothServiceListenerList
                ) {
            if (listener != null) {
                listener.onDeviceDisconnected();
            }
        }
    }

    private static void sendConnectFailed() {
        for (BluetoothServiceListener listener : mBlueToothServiceListenerList
                ) {
            if (listener != null) {
                listener.onDeviceConnectionFailed();
            }
        }
    }

    private static void addDataListener(BluetoothDataListener listener) {
        if (!mBlueToothDataListenerList.contains(listener)) {
            mBlueToothDataListenerList.add(listener);
        }
    }

    public static void unregisterDataListener(BluetoothDataListener listener) {
        if (listener != null && mBlueToothDataListenerList.contains(listener)) {
            mBlueToothDataListenerList.remove(listener);
        }
    }

    private static void sendData(int speed, int rpm, int shift) {
        for (BluetoothDataListener listener : mBlueToothDataListenerList
                ) {
            if (listener != null) {
                listener.onDataReceived(speed, rpm, shift);
            }
        }
    }

    public static void registerBluetoothData(final BluetoothDataListener listener) {
        if (bt != null && listener != null) {
            addDataListener(listener);
            bt.setOnDataReceivedListener(new BluetoothSPP.OnDataReceivedListener() {
                public void onDataReceived(byte[] data, String message) {
                    int _speed = 0;
                    int _rpm = 0;
                    int _shift = 0;
                    try {
                        if (System.currentTimeMillis() - startBtTime > 1000) {
                            BluetoothDataAnalysis bda = new BluetoothDataAnalysis(data);
                            _speed = (BluetoothDataAnalysis.s_speed == null) ? 0 : Integer.valueOf(BluetoothDataAnalysis.s_speed);
                            _rpm = (BluetoothDataAnalysis.s_rpm == null) ? 0 : Integer.valueOf(BluetoothDataAnalysis.s_rpm) * 100;
                            _shift = (BluetoothDataAnalysis.s_shift == null) ? 0 : Integer.valueOf(BluetoothDataAnalysis.s_shift);
                            sendData(_speed, _rpm, _shift);
                            startBtTime = System.currentTimeMillis();
                        }
                    } catch (NumberFormatException exception) {
                        LogUtils.e(TAG, "number format error " + _speed + "/" + _rpm + "/" + _shift);
                    }
                }
            });
        }
    }
}
